package com.dyit.websocket;

import com.dyit.config.RabbitMqConfig;
import com.dyit.dao.IBookDao;
import com.dyit.entity.Book;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@ServerEndpoint("/websocket")
@Component
public class WebSocketServer {
    @Autowired
    private IBookDao iBookDao;

    //静态变量，用来记录当前在线连接数，应该把它设计成线程安全的。
    private static final AtomicInteger nums = new AtomicInteger(0);
    private static final ConcurrentHashMap<String, Session> map = new ConcurrentHashMap<>();
    private final String ID = "id_";

    /**
     * 连接建立成功时调用的方法
     */
    @OnOpen
    public void onOpen(Session session){
        String id = ID + nums.incrementAndGet();
        log.info("用户id："+id + "进行WebSocket连接....");
        map.put(id,session);
        try {
            sendMessage("后台链接成功~~~");
        } catch (IOException e) {
            log.error("websocket异常！");
        }
    }

    /**
     * 实现服务器主动推送，onOpen里面用到了
     */
    public void sendMessage(String message) throws IOException {
        String id = ID + nums.get();//拿到当前id
        log.info("连接ID:" + id + "向客户端发送信息...");
        Session session = map.get(id);
        session.getBasicRemote().sendText(message);
    }
    /**
     * 连接关闭时用到的方法
     */
    @OnClose
    public void onClose(){
        map.remove(ID+nums.get());
        log.info("有一连接关闭！当前在线人数为"+map.size());
    }

    /**
     * 这个websocket负责监听队列里的book对象并将其通过ibookdao添加进数据库去
     */
    @RabbitListener(queues = RabbitMqConfig.DIRECT_QUEUE)
    public void getMessage(Book book, Channel channel) throws IOException {
        iBookDao.save(book);
        log.info("数据库拿取rabbitmq里的book对象了！"+book);
        sendMessage("图书："+book.getTitle()+"存入数据库成功！");
        log.info("rabbitmq里的数据被消费后，发送给前端...");
    }

    /**
     * 发生错误时
     */
    @OnError
    public void onError(Session session,Throwable error){
        log.error("发生错误");
        error.printStackTrace();
    }

}
